
module fft_3d

  use dimensions
  use fft_wrap


  complex, private   :: fx(jx)
  complex, private   :: fy(jy)
  complex, private   :: fz(jz)
  complex, private   :: fv(jv)

  integer, private   :: ix, iy, iz, iv, iDir


contains
!-------------------------------------------------------------------------------------
subroutine  fft_forward_x(arr3D)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout) :: arr3D(jz,jy,jx)

  do iy=1,jy
     do iz=1,jz 
        
        fx = arr3D(iz,iy,:)
        call dfftw_execute_dft(plan_xforward, fx, fx)
        fx = fx/float(jx)
        arr3D(iz,iy,:) = fx(:)

     end do
  enddo

end subroutine fft_forward_x

!-------------------------------------------------------------------------------------
subroutine  fft_backward_x(arr3D)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout) :: arr3D(jz,jy,jx)

  do iy=1,jy
     do iz=1,jz 

        fx = arr3D(iz,iy,:)
        call dfftw_execute_dft(plan_xbackward, fx, fx)
        arr3D(iz,iy,:) = fx(:)

     end do
  enddo

end subroutine fft_backward_x

!-------------------------------------------------------------------------------------
subroutine  fft_forward_y(arr3D)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout) :: arr3D(jz,jy,jx)

  do ix=1,jx
     do iz=1,jz 
        
        fy = arr3D(iz,:,ix)
        call dfftw_execute_dft(plan_yforward, fy, fy)
        fy = fy/float(jy)
        arr3D(iz,:,ix) = fy(:)

     end do
  enddo

end subroutine fft_forward_y

!-------------------------------------------------------------------------------------
subroutine  fft_backward_y(arr3D)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout) :: arr3D(jz,jy,jx)

  do ix=1,jx
     do iz=1,jz 

        fy = arr3D(iz,:,ix)
        call dfftw_execute_dft(plan_ybackward, fy, fy)
        arr3D(iz,:,ix) = fy(:)

     end do
  enddo

end subroutine fft_backward_y

!-------------------------------------------------------------------------------------
subroutine  fft_forward_z(arr3D)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout) :: arr3D(jz,jy,jx)

  do ix=1,jx
     do iy=1,jy 
        
        fz = arr3D(:,iy,ix)
        call dfftw_execute_dft(plan_zforward, fz, fz)
        fz = fz/float(jz)
        arr3D(:,iy,ix) = fz(:)

     end do
  enddo

end subroutine fft_forward_z

!-------------------------------------------------------------------------------------
subroutine  fft_backward_z(arr3D)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout) :: arr3D(jz,jy,jx)

  do ix=1,jx
     do iy=1,jy 

        fz = arr3D(:,iy,ix)
        call dfftw_execute_dft(plan_zbackward, fz, fz)
        arr3D(:,iy,ix) = fz(:)

     end do
  enddo

end subroutine fft_backward_z


!-------------------------------------------------------------------------------------
subroutine fft_forward_dfu_z(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

    do iDir = 1,jDir
        do ix=1,jx
           do iy=1,jy
              do iv=1,jv
                 fz(:) = dfu(iv,:,iy,ix,iDir)
                 call dfftw_execute_dft(plan_zforward, fz, fz)
                 dfu(iv,:,iy,ix,iDir) = fz(:)
              enddo
           end do
        enddo
     enddo

 end subroutine fft_forward_dfu_z

!-------------------------------------------------------------------------------------
subroutine fft_backward_dfu_z(dfu)
!-------------------------------------------------------------------------------------
  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

     do iDir = 1,jDir
        do ix=1,jx
           do iy=1,jy
              do iv=1,jv
                 fz(:) = dfu(iv,:,iy,ix,iDir)
                 call dfftw_execute_dft(plan_zbackward, fz, fz)
                 dfu(iv,:,iy,ix,iDir) = fz(:)
              enddo
           end do
        enddo
     enddo

end subroutine fft_backward_dfu_z

!-------------------------------------------------------------------------------------
subroutine fft_forward_dfu_v(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iy=1,jy
            do iz=1,jz
               fv(:) = dfu(:,iz,iy,ix,iDir)
               call dfftw_execute_dft(plan_vforward, fv, fv)
               dfu(:,iz,iy,ix,iDir)=fv(:)       
           enddo
         enddo
      enddo
   enddo
 
end subroutine fft_forward_dfu_v

!-------------------------------------------------------------------------------------
subroutine fft_backward_dfu_v(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

  do iDir = 1,jDir
      do ix=1,jx
         do iy=1,jy
            do iz=1,jz
               fv(:) = dfu(:,iz,iy,ix,iDir)
               call dfftw_execute_dft(plan_vbackward, fv, fv)
               dfu(:,iz,iy,ix,iDir)=fv(:)       
            enddo
         enddo
      enddo
   enddo

end subroutine fft_backward_dfu_v


!-------------------------------------------------------------------------------------
subroutine fft_forward_dfu_x(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

   do iDir = 1,jDir
      do iy=1,jy
         do iz=1,jz
            do iv=1,jv
               fx(:) = dfu(iv,iz,iy,:,iDir)
               call dfftw_execute_dft(plan_xforward, fx, fx)
               dfu(iv,iz,iy,:,iDir)=fx(:)       
           enddo
         enddo
      enddo
   enddo
 
end subroutine fft_forward_dfu_x

!-------------------------------------------------------------------------------------
subroutine fft_backward_dfu_x(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

   do iDir = 1,jDir
      do iy=1,jy
         do iz=1,jz
            do iv=1,jv
               fx(:) = dfu(iv,iz,iy,:,iDir)
               call dfftw_execute_dft(plan_xbackward, fx, fx)
               dfu(iv,iz,iy,:,iDir)=fx(:)       
           enddo
         enddo
      enddo
   enddo
 
end subroutine fft_backward_dfu_x

!-------------------------------------------------------------------------------------
subroutine fft_forward_dfu_y(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iz=1,jz
            do iv=1,jv
               fy(:) = dfu(iv,iz,:,ix,iDir)
               call dfftw_execute_dft(plan_yforward, fy, fy)
               dfu(iv,iz,:,ix,iDir)=fy(:)       
           enddo
         enddo
      enddo
   enddo
 
end subroutine fft_forward_dfu_y


!-------------------------------------------------------------------------------------
subroutine fft_backward_dfu_y(dfu)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: dfu(jv, jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iz=1,jz
            do iv=1,jv
               fy(:) = dfu(iv,iz,:,ix,iDir)
               call dfftw_execute_dft(plan_ybackward, fy, fy)
               dfu(iv,iz,:,ix,iDir)=fy(:)       
           enddo
         enddo
      enddo
   enddo
 
end subroutine fft_backward_dfu_y


!*************************************************************************************

!-------------------------------------------------------------------------------------
subroutine fft_forward_u_x(u)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: u(jz, jy, jx, jDir)

   do iDir = 1,jDir
      do iy=1,jy
         do iz=1,jz
            fx(:) = u(iz,iy,:,iDir)
            call dfftw_execute_dft(plan_xforward, fx, fx)
            u(iz,iy,:,iDir)=fx(:)       
         enddo
      enddo
   enddo
 
end subroutine fft_forward_u_x


!-------------------------------------------------------------------------------------
subroutine fft_backward_u_x(u)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: u(jz, jy, jx, jDir)

   do iDir = 1,jDir
      do iy=1,jy
         do iz=1,jz
            fx(:) = u(iz,iy,:,iDir)
            call dfftw_execute_dft(plan_xbackward, fx, fx)
            u(iz,iy,:,iDir)=fx(:)       
         enddo
      enddo
   enddo
 
end subroutine fft_backward_u_x



!-------------------------------------------------------------------------------------
subroutine fft_forward_u_y(u)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: u(jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iz=1,jz
            fy(:) = u(iz,:,ix,iDir)
            call dfftw_execute_dft(plan_yforward, fy, fy)
            u(iz,:,ix,iDir)=fy(:)       
         enddo
      enddo
   enddo
 
end subroutine fft_forward_u_y


!-------------------------------------------------------------------------------------
subroutine fft_backward_u_y(u)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: u(jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iz=1,jz
            fy(:) = u(iz,:,ix,iDir)
            call dfftw_execute_dft(plan_ybackward, fy, fy)
            u(iz,:,ix,iDir)=fy(:)       
         enddo
      enddo
   enddo
 
end subroutine fft_backward_u_y


!-------------------------------------------------------------------------------------
subroutine fft_forward_u_z(u)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: u(jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iy=1,jy
            fz(:) = u(:,iy,ix,iDir)
            call dfftw_execute_dft(plan_zforward, fz, fz)
            u(:,iy,ix,iDir)=fz(:)       
         enddo
      enddo
   enddo
 
end subroutine fft_forward_u_z


!-------------------------------------------------------------------------------------
subroutine fft_backward_u_z(u)
!-------------------------------------------------------------------------------------

  implicit none

  complex, intent(inout)   :: u(jz, jy, jx, jDir)

   do iDir = 1,jDir
      do ix=1,jx
         do iy=1,jy
            fz(:) = u(:,iy,ix,iDir)
            call dfftw_execute_dft(plan_zbackward, fz, fz)
            u(:,iy,ix,iDir)=fz(:)       
         enddo
      enddo
   enddo
 
end subroutine fft_backward_u_z


!-------------------------------------------------------------------------------------


end module fft_3d
